<?php
/**
 * @desc 助手（点赞/评论）生成队列操作类
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2019/3/4
 * Time: 17:11
 */
namespace App\Console\Commands;

use App\Models\Admin\Activity;
use Illuminate\Console\Command;
use App\Models\MediaLikeConfig;
use App\Jobs\AssistantQueue;
use App\Models\Media;
use App\Models\MediaCommentConfig;
use App\Models\ActivityConfig;
use App\Jobs\SettlementQueue;
use Illuminate\Support\Facades\Redis;

class assistant extends Command
{
    protected $signature  = 'assistant:send {action}';
    private $page_size = 100;
    private $page_offset = 99;  // $page_size - 1

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        // 获取参数，调用方法
        $action = $this->argument('action');
        $this->$action();
        sleep(60);
        dd(1);
    }

    /**
     * @desc 生成视频点赞队列
     */
    public function generate_media_like_queue()
    {
        $queue_time = time();
        $where_arr = [['status','=', 2], ['execution_time', '<=', $queue_time], ['start_time', '<=', $queue_time]];
        $fields = ['id', 'media_type', 'frequency', 'cycle_type', 'cycle_time', 'end_time', 'execution_time', 'uid', 'media_id', 'account_num'];
        $config_list = MediaLikeConfig::where($where_arr)->get($fields)->toArray();
        if(empty($config_list)) {
            return true;
        }

        foreach($config_list as $config) {
            if($config['end_time'] < $queue_time) {
                MediaLikeConfig::where(['id' => $config['id']])->update(['status' => 3, 'updated_at' => time2date($queue_time)]);    // 结束该配置
                continue;
            }
            // 处理助手的下一次的执行时间
            if($config['cycle_type'] == 1) {
                // 天
                $cycle_time = 24*3600;
            } else if($config['cycle_type'] == 2) {
                // 小时
                $cycle_time = 3600;
            } else if($config['cycle_type'] == 3) {
                // 分
                $cycle_time = 60;
            } else {
                continue;
            }

            // 计算下一次执行时间
            $execution_time = $cycle_time * $config['cycle_time'] + $queue_time;
            $data = ['updated_at' => time2date($queue_time), 'execution_time' =>  $execution_time];
            if($execution_time >= $config['end_time']) {
                $data['status'] = 3;    // 处理配置结束
            }

            $rs = MediaLikeConfig::where(['id' => $config['id'], 'execution_time' => $config['execution_time']])->update($data);
            if(!$rs) {
                continue;
            }
            $queue_data = ['action' => 'media_like_queue', 'data' => $config];

            // 处理视频表数据量大的问题(以分页去处理)
            $where_arr = ['is_delete' => 0, 'is_private' => 0, 'is_forward' => 0, 'status' => 1];
            if($config['media_type'] == 1) {
                $total = Media::where($where_arr)->count();
            } elseif($config['media_type'] == 2) {
                $where_arr['uid'] = $config['uid'];
                $total = Media::where($where_arr)->count();
            } elseif($config['media_type'] == 3) {
                $media_ids = explode(',', $config['media_id']);
                $total = Media::where($where_arr)->whereIn('id', $media_ids)->count();
            }else {
                continue;
            }

            $total_page = (int)ceil($total/$this->page_size);
            $fields = ['id', 'like', 'is_like', 'uid', 'is_participate_activity'];
            for($i=1;$i<=$total_page;$i++) {
                $offset = ($i - 1) * $this->page_size;
                if($config['media_type'] == 3) {
                    $media_list = Media::where($where_arr)->whereIn('id', $media_ids)->skip($offset)->take($this->page_size)->orderBy('id', 'ASC')->get($fields)->toArray();
                } else {
                    $media_list = Media::where($where_arr)->skip($offset)->take($this->page_size)->orderBy('id', 'ASC')->get($fields)->toArray();
                }

                foreach($media_list as $media) {
                    $queue_data['media'] = $media;
                    dispatch((new AssistantQueue($queue_data))->onQueue('assistant_queue'));
                    sleep(2);
                }
            }
        }

        return true;
    }

    /**
     * @desc 生成视频评论的队列
     */
    public function generate_media_comment_queue()
    {
        $queue_time = time();
        $where_arr = [['status','=', 2], ['execution_time', '<=', $queue_time], ['start_time', '<=', $queue_time]];
        $fields = ['id', 'media_type', 'frequency', 'cycle_type', 'cycle_time', 'comment_content', 'end_time', 'execution_time'];
        $config_list = MediaCommentConfig::where($where_arr)->get($fields)->toArray();
        if(empty($config_list)) {
            return true;
        }

        foreach($config_list as $config) {
            if($config['end_time'] < $queue_time) {
                MediaCommentConfig::where(['id' => $config['id']])->update(['status' => 3]);    // 结束该配置
                continue;
            }
            if($config['cycle_type'] == 1) {
                $cycle_time = 24*3600;
            } else if($config['cycle_type'] == 2) {
                // $cycle_time = 3600;
                continue;
            } else if($config['cycle_type'] == 3) {
                // $cycle_time = 60;
                continue;
            } else {
                continue;
            }

            // 计算下一次执行时间
            $execution_time = $cycle_time * $config['cycle_time'] + $queue_time;
            $data = ['updated_at' => $queue_time, 'execution_time' =>  $execution_time];
            if($execution_time > $config['end_time']) {
                $data['status'] = 3;
            }

            // 修改下一次执行的时间
            $rs = MediaCommentConfig::where(['id' => $config['id'], 'execution_time' => $config['execution_time']])->update($data);
            if(!$rs) {
                continue;
            }

            // 处理视频对象条件，处理视频表数据量大的问题(以分页去处理)
            $where_arr = ['is_delete' => 0];
            if($config['media_type'] == 1) {
                $where_arr['is_private'] = 0;
                $where_arr['is_forward'] = 0;
                $where_arr['status'] = 1;
            } else {
                continue;
            }

            // 按分页写入队列(每次执行100页，每页100条视频)
            $queue_data = ['action' => 'media_comment_queue', 'data' => $config];
            $total = Media::where($where_arr)->count();
            $total_page = (int)ceil($total/$this->page_size);
            for($i=1;$i<=$total_page;$i++) {
                if(($i%100) == 0) {
                    $queue_data['start_page'] = $i - $this->page_offset;
                    $queue_data['end_page'] = $i;
                    dispatch((new AssistantQueue($queue_data))->onQueue('assistant_queue'));
                } else if($i == $total_page) {
                    if($total <= $this->page_size) {
                        $queue_data['start_page'] = 1;
                    } else {
                        $queue_data['start_page'] = $i - ($i % 100) + 1;
                    }
                    $queue_data['end_page'] = $i;
                    dispatch((new AssistantQueue($queue_data))->onQueue('assistant_queue'));
                }
            }
        }

        return true;
    }

    /**
     * @desc 生成邀请结算列表
     */
    public function create_invite_settlement_queue()
    {
        $current_time = time();
        $where_arr = [
            ['start_time', '<=', $current_time],
            ['end_time', '>=', $current_time],
            ['status','=', '1'],
            ['next_settlement_time', '<', $current_time],
            ['activity_type', '=', 1]   // 邀请活动类型
        ];

        $activity_info = ActivityConfig::where($where_arr)->first(['id', 'settlement_type', 'next_settlement_time', 'last_settlement_time', 'activity_strategy']);
        if(empty($activity_info)) {
            sleep(60);
            dd('no activity');
        }

        // 减去1为下一次执行时间为周日(23:59:59)或这个月的最后一天(23:59:59)
        $next_settlement_time = $activity_info->settlement_type == 1 ? (strtotime('+1 week last monday')-1) : (strtotime(date('Y-m-1',strtotime('next month'))) - 1);

        // 执行后，下一次的执行时间为重新计算的，下面加1，开始时间为周一（00:00:00）或1号(00:00:00)
        $data = ['last_settlement_time' => $activity_info->next_settlement_time ? ($activity_info->next_settlement_time + 1): ($current_time - 1), 'next_settlement_time' => $next_settlement_time];
        $rs = ActivityConfig::where(['id' => $activity_info->id, 'next_settlement_time' => $activity_info->next_settlement_time])->update($data);
        if($rs) {
            $queue_data = ['action' => 'create_invite_settlement', 'data' => $activity_info->toArray()];
            dispatch((new SettlementQueue($queue_data))->onQueue('settlement_queue'));
        }

        sleep(60);
        dd('create activity queue');
    }

    /**
     * @desc 处理后台结算类型变更的数据
     */
    public function change_invite_settlement_queue()
    {
        $active_info = Redis::lpop("Invite_Settlement_data");
        if(empty($active_info)) {
            return true;
        }

        $queue_data = ['action' => 'create_invite_settlement', 'data' => json_decode($active_info, true)];
        dispatch((new SettlementQueue($queue_data))->onQueue('settlement_queue'));

        return true;
    }
}